<?php
/**
 * 路由
 * 
 * @package SF
 * @author Shuky
 * @since v1.0
 * @version $Id: Router.php 95 2011-01-11 18:30:09Z shukyoo@gmail.com $
 */
namespace SF;

class Router
{
    /**
     * @var Request
     */
    protected $_request = null;
    
    // 自身单件实例类
    protected static $_instance = null;
    
    // 控制
    protected $_controller = 'index';
    
    // 动作
    protected $_action = 'index';

	// 默认首要参数索引
	protected $_index = '';
    
    
    /**
     * 自身单件实例获取
     */
    public static function getInstance()
    {
    	if (null === self::$_instance) {
    		self::$_instance = new self();
    	}
    	return self::$_instance;
    }
    
    
    /**
     * 构造，按/controller/action/index方式解析请求
     * @todo 注意一下这里跟parseLink的纠结，如何去统一提取规则
     */
    protected function __construct()
    {
    	$path = $this->getRequest()->getPathInfo();
		$path = explode('/', $path);
		if (!empty($path[0])) {
			$this->_controller = trim(strtolower($path[0]));
		}
		if (!empty($path[1])) {
			$this->_action = trim(strtolower($path[1]));
		}
		if (isset($path[2])) {
			$this->_index = trim($path[2]);
		}
    }
    
    
    /**
     * 按规则处理路径串
     * 路径格式：controller/action/index
     * 默认以此格式作为链接样式
     * 返回绝对Url路径
     */
    public function parseLink($path)
    {
		if (strpos($path, './') === 0) {
			$path = substr($path, 2);
			$path = $this->getController() .'/'. $path;
		}
        if (strpos($path, '/') === 0) {
        	$path = substr($path, 1);
        }
    	return $this->getRequest()->getBaseUrl() .'/'. $path;
    }
    
    
    /**
     * 获取请求
     * @return Request
     */
    public function getRequest()
    {
        if (null === $this->_request) {
    		$this->_request = Request::getInstance();
    	}
    	return $this->_request;
    }
    
    
    /**
     * 路由解析和导向
     */
    public function dispatch()
    {
	    $controlClass = 'APP\\C\\'. ucfirst($this->_controller);
	    if (!class_exists($controlClass)) {
	    	$this->notFound();
	    }
		$controlClass = new $controlClass();
		$action = $this->_action .'Action';
		if (!method_exists($controlClass, $action)) {
			$this->notFound();
		}
		$controlClass->$action();
    }
    
    
    /**
     * 404导向
     */
    public function notFound($toUrl = '/home/notfound')
    {
    	$this->redirect($toUrl);
    }
    
    
    /**
     * 转向
     */
	public function redirect($toUrl)
	{
	    $toUrl = (strpos($toUrl, 'http://') === false) ? $this->parseLink($toUrl) : $toUrl;
		header('Location: '. $toUrl);
        exit;
	}


	/**
	 * 生成链接
	 */
	public function genQuery($path='', $params = array(), $append = true)
	{
        // 基础
        $base = $this->getRequest()->getBaseUrl();
        if (strchr($base, '/') != '/') {
            $base .= '/';
        }
        // 组织path
        $path = ltrim($path, '/');
        if ($append) {
            $path = $this->getRequest()->getPathInfo() . '/' . $path;
        }
        $path = trim($path, '/');
        // 组织参数
        $qstr = $append ? $this->getRequest()->getQueryString() : '';
        if ($params) {
            $aq = array();
            foreach ($params as $k=>$v) {
                if ($v !== '') {
                    $aq[] = $k .'='. $v;
                }
            }
            if (!empty($aq)) {
                $qstr .= (($qstr ? '&' : '') . implode('&', $aq));
            }
        }
        if ($qstr) {
            $qstr = '?'. $qstr;
        }
        return $base . $path . $qstr;
	}

	
	/**
	 * 获取Controller
	 */
	public function getController()
	{
		return $this->_controller;
	}
	
	
	/**
	 * 获取和设置Action
	 */
	public function getAction()
	{
		return $this->_action;
	}
	public function setAction($action)
	{
		$this->_action = $action;
	}


	/**
	 * 获取和设置Index
	 */
	public function getIndex()
	{
		return $this->_index;
	}
	public function setIndex($index)
	{
		$this->_index = $index;
	}
}